import React, { useState, useMemo, useEffect } from 'react';
import { urlWork } from 'nui';
import { BtImport, export_csv_file, for_obj, no_del, Btn, WaitUmd, obj_str, CurTip, PanelFind, filter_row, useCmd, useHigh, is_empty,
    obj_bool, BtMenu, loc, GridTable } from 'sui';
import { get_cur_main } from '../cmd/base';
import { tree_col, build_sub } from '../cmd/tree';
import { build_it, build_key, load_id } from '../cmd/load';
import { ValueDlg } from '../ctl/value';
import { FixDlg } from '../ctl/fix';
import { RealView } from './real';

const ValueView = ({ mod, reload }) => {
    const [main, setMain] = useState();
    const [plc, setPlc] = useState();
    const [open, setOpen] = useState(false);
    const [fix, setFix] = useState();
    const [open_fix, openFix] = useState(false);
    const [row, setRow] = useState();
    const [fin, setFin] = useState();
    const umd = useCmd();
    const [high] = useHigh(140, 100);

    useEffect(() => {
        load_id(mod, v => {
            setFix(v.f);

            const plc_id = obj_str(v, "plc");

            if (plc_id) {
                load_id(plc_id, p => {
                    setPlc(p);

                    build_it(v);
                    setMain(v);

                    get_cur_main(v, setRow);
                });
            }
        });

        setFin(null);
    }, [mod]);

    const filterRow = useMemo(() => {
        const lst = ["id", "name"];

        if (is_empty(row)) {
            return null;
        }

        return filter_row(row, lst, umd.filter);
    }, [row, umd.filter]);

    if (fin === "real") {
        return <RealView plc={plc} main={main} hreturn={() => setFin(null)}/>;
    }

    const hreload = (v) => {
        setFix(v.f);
        build_it(v);
        setMain(v);

        get_cur_main(v, setRow);
    };

    const reload_data = (tmp) => {
        let cmd = {};
        const igk = build_key();

        for_obj(main, (k, v) => {
            if (igk.has(k)) {
                return;
            }

            cmd[k] = v;
        });

        const val = [];

        tmp.forEach(d => {
            const t = {};

            for_obj(d, (k, v) => {
                if (igk.has(k) || k === "id" || k === "uid") {
                    return;
                }

                t[k] = v;
            });

            val.push(t);
        });

        cmd["v"] = val;

        urlWork(null, "config/update", {mod: "it", v: [cmd]},
            r => {
                load_id(mod, v => {
                    hreload(v);
                    umd.endWait();
                });
            }, e => umd.setWrong(loc("xgsb")));
    };

    const hadd = (v) => {
        umd.startWait();

        let index = null;
        if (umd.cur) {
            index = umd.cur.index;
        }

        let tmp = [];
        if (!is_empty(row)) {
            tmp = row.filter(d => d.index && d.index !== index);
        }

        tmp.push(v);
        tmp = tmp.sort((a, b) => a.k > b.k);

        reload_data(tmp);
    };

    const hdel = (k) => {
        if (no_del()) {
            return;
        }

        umd.startWait();

        const tmp = [];

        row.forEach(d => {
            if (d.k === k) {
                return;
            }

            tmp.push(d);
        });

        reload_data(tmp);
    };

    const lst = [
        {key: "del", val: loc("sc")},
        {key: "edit", val: loc("bj")},
        {key: "copy", val: loc("cmd_134")},
    ];

    const hAction = (d, v) => {
        if (v === "del") {
            hdel(d.k);
        }
        else if (v === "edit") {
            umd.hcur(d);
            setOpen(true);
        }
        else if (v === "add") {
            umd.hcur(null);
            setOpen(true);
        }
        else if (v === "fix") {
            umd.hcur(null);
            openFix(true);
        }
        else if (v === "copy") {
            umd.hcur(d, "copy");
            setOpen(true);
        } else if (v === "out") {
            const val = main["v"];
            if (is_empty(val)) {
                return;
            }

            const set = new Set();

            const drow = [];
            const dcol = [];

            val.forEach(d => {
                for_obj(d, (k, kv) => {
                    if (set.has(k)) {
                        return;
                    }
                    set.add(k);

                    dcol.push(k);
                });
            });

            val.forEach(d => {
                const tmp = [];
                dcol.forEach(k => tmp.push(obj_str(d, k)));

                drow.push(tmp);
            });

            export_csv_file(`${mod}_data`, dcol, drow);
        }
    };

    const hIn = (data, umd) => {
        if (is_empty(data)) {
            return;
        }

        const val = [];
        const set = new Set();

        data.forEach(d => {
            for_obj(d, (k, v) => {
                if (v === "true" || v === "false") {
                    d[k] = obj_bool(d, k);
                }
            });

            set.add(obj_str(d, "k"));

            val.push(d);
        });

        umd.startWait();

        let tmp = [];

        if (!is_empty(row)) {
            tmp = row.filter(d => !set.has(obj_str(d, "k")));
        }

        val.forEach(d => tmp.push(d));

        tmp = tmp.sort((a, b) => a.k > b.k);

        reload_data(tmp);
    };

    const col = [
        {name: loc("xh"), key: 'index', width: 80, frozen: true},
        {name: loc("mbq"), key: 'm', width: 400, frozen: true, formatter: props => tree_col(props.row, v => build_sub(row, v, setRow))},
        {name: loc("cz"), key: 'e_opt', width: 40, frozen: true, formatter: props => {
            const d = props.row;
            if (d.index) {
                return <BtMenu lst={lst} hcmd={v => hAction(d, v)}/>;
            }

            return null;
        }},
        {name: loc("zw_19"), key: 'k', width: 200},
        {name: loc("lx"), key: 'ltp', width: 140},
    ];

    const Left = () => <CurTip label={obj_str(plc, "name")} cur={obj_str(main, "ltp")}>{obj_str(main, "name")}</CurTip>;

    const Right = () => (
        <div className="inline-flex">
            <BtImport className="mr-4" label={loc("cmd_49")} umd={umd} hcmd={hIn}/>
            <Btn className="mr-4" hcmd={() => hAction(null, "out")}>{loc("cmd_50")}</Btn>
            <Btn className="mr-4" hcmd={() => hAction(null, "fix")}>{loc("mg_282")}</Btn>
            <Btn className="mr-4" color="green" hcmd={() => hAction(null, "add")}>{loc("cmd_40")}</Btn>
            <Btn className="mr-4" hcmd={() => setFin("real")}>{loc("mg_162")}</Btn>
        </div>
    );

    return (
        <div className="ml-8">
            <PanelFind left={<Left/>} right={<Right/>} cl="gray" hcmd={v => umd.setFilter(v)}/>
            <GridTable col={col} row={filterRow} high={high}/>
            <ValueDlg open={open} setOpen={setOpen} hcmd={hadd} umd={umd} main={row} ptype={obj_str(plc, "type")} fix={main}/>
            <FixDlg open={open_fix} setOpen={openFix} mod={mod} hcmd={v => hreload(v)} data={fix}/>
            <WaitUmd umd={umd}/>
        </div>
    );
};

export {ValueView};
